part of interna;

// represents a cursor in the buffer
class Cursor extends Object with Observable {
   @observable int line;
   @observable int char;
   DivElement curs;

   Cursor (int line, int char, Function updt) {
      if (line == null) throw null_arg;
      if (char == null) throw null_arg;
      if (updt == null) throw null_arg;
      changes.listen(updt);
      this.line = line;
      this.char = char;
      curs = makeCursor();
   }

   bool get isValid {
      if (line < 0) return false;
      if (char < 0) return false;
      return true;
   }
}

// represents a single line in the buffer
class Line extends Object with Observable {
   @observable String plain;
   SpanElement clrd;
   Line prev;
   @observable Line next;

   Line (String plain, Function updt) {
      if (plain == null) throw null_arg;
      if (updt == null) throw null_arg;
      changes.listen(updt);
      this.plain = plain;
      clrd = makeLine();
   }

   // returns the line being removed
   Line remove () {
      clrd.remove();
      Line before = this.prev;
      Line after = this.next;
      if (before == null && after == null) {
         return this;
      }
      if (before == null) {
         after.prev = null;
         return this;
      }
      if (after == null) {
         before.next = null;
         return this;
      }
      before.next = after;
      after.prev = before;
      return this;
   }

   // inserts the given line before this line
   void insertBefore (Line that) {
      if (that == null) throw null_arg;
      Line temp = this.prev;
      this.prev = that;
      that.prev = temp;
      that.next = this;
      if (temp != null) temp.next = that;
   }

   // inserts the given line after this line
   void insertAfter (Line that) {
      if (that == null) throw null_arg;
      Line temp = this.next;
      this.next = that;
      that.next = temp;
      that.prev = this;
      if (temp != null) temp.prev = that;
   }

   // returns number of lines before this line (exclusive)
   int linesBefore () {
      int cnt = 0;
      for (Line temp = this.prev; temp != null; temp = temp.prev) cnt++;
      return cnt;
   }

   // returns number of lines after this line (exclusive)
   int linesAfter () {
      int cnt = 0;
      for (Line temp = this.next; temp != null; temp = temp.next) cnt++;
      return cnt;
   }
}
